package com.xxwy.springboot.webflux.controller;

import com.xxwy.springboot.webflux.document.User;
import com.xxwy.springboot.webflux.repository.UserRepository;
import com.xxwy.springboot.webflux.util.CheckUtil;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import javax.validation.Valid;

/**
 * @author xxwy
 */
@RestController
@RequestMapping("user")
public class UserController {


    private final UserRepository repository;

    /**
     * 使用构造函数
     *
     * @param repository
     */
    public UserController(UserRepository repository) {
        this.repository = repository;
    }

    @GetMapping("/all")
    public Flux<User> getAll() {
        return repository.findAll();
    }

    /**
     * 使用sse多次返回数据
     *
     * @return
     */
    @GetMapping(value = "/stream/all", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<User> getStreamAll() {
        return repository.findAll();
    }


    /**
     * 增加
     */
    @PostMapping(value = "/")
    public Mono<User> createUser(@Valid @RequestBody User user) {
        // spring data jpa里面，新增和修改都是save,有id是修改，无id是新增
        //根据实际情况是否置null
        CheckUtil.checkName(user.getName());
        user.setId(null);
        return this.repository.save(user);
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    @DeleteMapping("/{id}")
    public Mono<ResponseEntity<Void>> deleteUser(@PathVariable String id) {
        //返回Mono就是异步的Mono实现了发送方
        return this.repository.findById(id)
                .flatMap(user -> this.repository.delete(user))
                .then(Mono.just(new ResponseEntity<Void>(HttpStatus.OK)))
                .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));

    }


    /**
     * 改
     */
    @PutMapping("/{id}")
    public Mono<ResponseEntity<User>> updateUser(
            @PathVariable String id, @Valid @RequestBody User user) {
        return this.repository.findById(id)
                //转换数据,返回一个Mono
                .flatMap(u -> {
                    CheckUtil.checkName(u.getName());
                    u.setAge(user.getAge());
                    u.setName(user.getName());
                    return this.repository.save(u);
                })
                //转换数据
                .map(u -> new ResponseEntity<User>(u, HttpStatus.OK))
                .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }


    /**
     * 查
     *
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public Mono<ResponseEntity<User>> selectUserByID(
            @PathVariable String id) {
        return this.repository.findById(id)
                .map(u -> new ResponseEntity<User>(u, HttpStatus.OK))
                .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));

    }


    /**
     * 查10-20岁
     */
    @GetMapping(value = "/age/{start}/{end}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<User> selectUserByAge(
            @PathVariable int start,
            @PathVariable int end) {
        return this.repository.findByAgeBetween(start,end);
    }

    /**
     * 查老年人；45-50
     */
    @GetMapping(value = "/age/old",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<User> selectOldUser(){
        return this.repository.oldUser();
    }

}
